home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / du_lib / xacc2 / xacctest.c < prev    next >
C/C++ Source or Header  |  1994-09-14  |  13KB  |  452 lines

  1. /* XACCTEST.PRG/ACC - ein XACC-Beispiel und Testprogramm
  2.     (c) 1993 Harald Sommerfeldt @ KI im Maus-Netz
  3.     E-Mail:  Harald_Sommerfeldt@ki.maus.de */
  4.  
  5. /* Geschichte:
  6.     22.03.93: erste Version
  7.     05.09.93: erste ver”ffentlichte Version
  8.     09.09.93: l„uft nun auch unter Speicherschutz (MiNT)
  9. */
  10.  
  11. /*
  12.     ++craig
  13.     PATCHES FOR LATTICE C 5.52 [13/9/94] by Craig Graham.
  14. */
  15.  
  16. /* Hinweise:
  17.     - dieses Programm l„uft sowohl als ACC als auch als PRG
  18.     - dieses Programm wurde mit Tabweite 3 entwickelt
  19. */
  20.  
  21.  
  22. #include <aes.h>
  23. #include <tos.h>
  24. #include <stdarg.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include "xacc.h"
  28. #include "xacctest.h"
  29.  
  30. extern int _XMODE;
  31.  
  32. typedef enum { FALSE, TRUE } bool;
  33.  
  34. short    ap_id, menu_id;        /* AES Application-ID und Menu-ID */
  35. OBJECT *menu;                    /* Menbaum */
  36. char    path[80], name[14];    /* fr fsel_input() */
  37.  
  38. bool    handle_mesag( const short *msgbuf );
  39.  
  40.  
  41. /* form_alert() mit Format-String */
  42. short    form_falert( short defbut, const char *fastring, ... )
  43. {
  44.     va_list    argposhort;
  45.     static char buffer[256];
  46.     short    button;
  47.  
  48.     wind_update( BEG_UPDATE );
  49.     va_start( argposhort, fastring );
  50.     vsprintf( buffer, fastring, argposhort );
  51.     va_end( argposhort );
  52.     button = form_alert( defbut, buffer );
  53.     wind_update( END_UPDATE );
  54.     return button;
  55. }
  56.  
  57. /* vereinfachtes rsrc_gaddr() */
  58. OBJECT    *rsrc_gtaddr( short index )
  59. {
  60.     OBJECT    *tree;
  61.  
  62.     rsrc_gaddr( 0, index, &tree );
  63.     return tree;
  64. }
  65.  
  66.  
  67. /* dem Benutzer eine Liste der aktiven XACC-Applikationen anbieten;
  68.    diese Routine kann nur max. 8 Eshortr„ge verwalten (in einem richtigen
  69.    Programm sollte man natrlich alle anbieten), damit sie kurz und
  70.    knapp (und verst„ndlich) bleibt
  71.     info   : Infozeile, worum es berhaupt geht
  72.     groups : Bitmaske, welche Groups wir brauchen
  73.     zurckgegeben wird der Index des XACC-Eshortrages oder NIL (-1) */
  74. #define NXACC 8    /* soviele Eshortr„ge passen in unsere Liste */
  75. short    do_list( const char *info, short groups )
  76. {
  77.     OBJECT    *dialog;
  78.     short        obj, i, x, y, w, h;
  79.     TEDINFO *t;
  80.  
  81.     dialog = rsrc_gtaddr( XACCLIST );
  82.     
  83.     /* Titel setzen und Unterstreichung anpassen */
  84.     (char *)(dialog[XL_TITLE].ob_spec) = (char *)info;
  85.     dialog[XL_TITUN].ob_width = dialog[XL_TITLE].ob_width / (short)strlen( "STRING" ) * (short)strlen( info );
  86.  
  87.     /* Eshortr„ge in die Liste eshortragen */
  88.     for ( i = 0; i < NXACC; i++ ) {
  89.         if ( xaccs[i].id >= 0 ) {
  90.             t=(TEDINFO*)(dialog[XL_ENTRY+i].ob_spec);
  91.             sprintf( t->te_ptext, "%-30s %2d %#06x",
  92.                 xaccs[i].name, xaccs[i].id, xaccs[i].groups );
  93.             if ( xaccs[i].groups & groups )
  94.                 dialog[XL_ENTRY+i].ob_state &= ~DISABLED;
  95.             else
  96.                 dialog[XL_ENTRY+i].ob_state |= DISABLED;
  97.         }
  98.         else {
  99.             t=(TEDINFO*)(dialog[XL_ENTRY+i].ob_spec);
  100.             sprintf( t->te_ptext, "%-40s", "" );
  101.             dialog[XL_ENTRY+i].ob_state |= DISABLED;
  102.             dialog[XL_ENTRY+i].ob_state &= ~SELECTED;
  103.         }
  104.     }
  105.  
  106.     /* Dialog darstellen */
  107.     form_center( dialog, &x, &y, &w, &h );
  108.     wind_update( BEG_UPDATE );
  109.     form_dial( FMD_START, 0, 0, 0, 0, x, y, w, h );
  110.     objc_draw( dialog, 0, MAX_DEPTH, x, y, w, h );
  111.     obj = form_do( dialog, 0 );
  112.     dialog[obj].ob_state &= ~SELECTED;
  113.     if ( obj == XL_OK ) {
  114.         for ( i = 0; i < NXACC; i++ ) {
  115.             if ( dialog[XL_ENTRY+i].ob_state & SELECTED ) break;
  116.         }
  117.         if ( i == NXACC ) i = -1;
  118.     }
  119.     else i = -1;
  120.     form_dial( FMD_FINISH, 0, 0, 0, 0, x, y, w, h );
  121.     wind_update( END_UPDATE );
  122.  
  123.     /* Index zurckgeben */
  124.     return i;
  125. }
  126.  
  127. /* eine Taste mittels ACC_KEY versenden */
  128. void    do_key( short i )
  129. {
  130.     OBJECT    *dialog = rsrc_gtaddr( SENDKEY );
  131.     short        msgbuf[8], x, y, w, h;
  132.  
  133.     wind_update( BEG_UPDATE );
  134.     form_center( dialog, &x, &y, &w, &h );
  135.     form_dial( FMD_START, 0, 0, 0, 0, x, y, w, h );
  136.     objc_draw( dialog, 0, MAX_DEPTH, x, y, w, h );
  137.     wind_update( BEG_MCTRL );
  138.     msgbuf[0] = ACC_KEY;
  139.     msgbuf[1] = ap_id;
  140.     msgbuf[2] = 0;
  141.     msgbuf[3] = evnt_keybd();
  142.     appl_write( xaccs[i].id, 16, msgbuf );
  143.     wind_update( END_MCTRL );
  144.     form_dial( FMD_FINISH, 0, 0, 0, 0, x, y, w, h );
  145.     wind_update( END_UPDATE );
  146. }
  147.  
  148. /* einen Text mittels ACC_TEXT versenden */
  149. void    do_text( short i )
  150. {
  151.     OBJECT *dialog;
  152.     TEDINFO *t;
  153.     short msgbuf[8], x, y, w, h, obj;
  154.     char *buffer;
  155.     
  156.     dialog = rsrc_gtaddr( SENDTEXT );
  157.  
  158.     wind_update( BEG_UPDATE );
  159.     form_center( dialog, &x, &y, &w, &h );
  160.     form_dial( FMD_START, 0, 0, 0, 0, x, y, w, h );
  161.     objc_draw( dialog, 0, MAX_DEPTH, x, y, w, h );
  162.     obj = form_do( dialog, 0 );
  163.     dialog[obj].ob_state &= ~SELECTED;
  164.     if ( obj == STXT_OK ) {
  165.         buffer = xacc_malloc( 100 );
  166.         if ( buffer != NULL ) {
  167.             t=(TEDINFO*)(dialog[STXT_TXT].ob_spec);
  168.             strcpy( buffer, t->te_ptext );
  169.  
  170.             msgbuf[0] = ACC_TEXT;
  171.             msgbuf[1] = ap_id;
  172.             msgbuf[2] = 0;
  173.             *(char **)(msgbuf+4) = buffer;
  174.             appl_write( xaccs[i].id, 16, msgbuf );
  175.         }
  176.         else form_falert( 1, "[3][* Fehler bei xacc_malloc()][ OK ]" );
  177.     }
  178.     form_dial( FMD_FINISH, 0, 0, 0, 0, x, y, w, h );
  179.     wind_update( END_UPDATE );
  180. }
  181.  
  182. /* ein Stck Datei versenden */
  183. short    do_sendpiece( short dest_id, short type, short das_ende, const char *addr, long length )
  184. {
  185.     short    msgbuf[8], dummy, event, keycode;
  186.  
  187.     if ( xacc_send( dest_id, type, addr, length, das_ende ) ) {
  188.  
  189.         /* auf Best„tigung warten, Timeout: 30 Sekunden */
  190.         for (;;) {
  191.             event = evnt_multi( MU_MESAG|MU_KEYBD|MU_TIMER, 2, 1, 1,
  192.                 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, msgbuf, 30*1000, 0,
  193.                 &dummy, &dummy, &dummy, &dummy, &keycode, &dummy );
  194.  
  195.             /* UNDO gedrckt: keine Lust mehr */
  196.             if ( (event & MU_KEYBD) && keycode == 0x6100 ) {    /* UNDO */
  197.                 if ( form_falert( 1, "[2][ |Senden abbrechen?][Ja|Nein]" ) == 1 )
  198.                     break;
  199.             }
  200.  
  201.             /* eine Nachricht fr uns */
  202.             if ( event & MU_MESAG ) {
  203.                 if ( msgbuf[0] == ACC_ACK ) {
  204.                     /* alles paletti: weiter im Text */
  205.                     if ( msgbuf[3] ) return TRUE;
  206.                     /* ansonsten: das Leben ist hart und ungerecht */
  207.                     form_falert( 1, "[3][ |Keiner mag mich!][Schnff]" );
  208.                     break;
  209.                 }
  210.                 if ( msgbuf[0] != MN_SELECTED && msgbuf[0] != AC_OPEN )
  211.                     handle_mesag( msgbuf );
  212.             }
  213.  
  214.             /* 30 Sekunden vorbei: Timeout */
  215.             if ( event & MU_TIMER ) {
  216.                 form_falert( 1, "[3][ |Timeout beim Senden][Abbruch]" );
  217.                 break;
  218.             }
  219.         }
  220.     }
  221.  
  222.     return FALSE;
  223. }
  224.  
  225. /* eine Datei mittels 'message' versenden */
  226. void    do_sendfile( short i, const char *fileext, short message )
  227. {
  228.     char    fpath[128], *buffer;
  229.     short    button, fh;
  230.     long    l;
  231.  
  232.     /* ein wenig Vorbereitung fr fsel_input()... */
  233.     if ( *path == '\0' ) {
  234.         path[0] = Dgetdrv() + 'A';
  235.         path[1] = ':';
  236.         Dgetpath( path+2, 0 );
  237.         strcat( path+2, "\\" );
  238.     }
  239.     strcat( strcpy( strrchr( path, '\\' ) + 1, "*." ), fileext );
  240.     if ( strchr( name, '.' ) != NULL ) strcpy( strchr( name, '.' ) + 1, fileext );
  241.  
  242.     /* Dateiauswahl aufrufen */
  243.     if ( fsel_input( path, name, &button ) && button ) {
  244.  
  245.         /* Bastelstunde: wir basteln und einen Dateinamen */
  246.         strcpy( strrchr( strcpy( fpath, path ), '\\' ) + 1, name );
  247.  
  248.         /* Handwerkerstunde: wir ”ffnen eine Datei */
  249.         if ( (l = Fopen( fpath, FO_READ )) >= 0L ) {
  250.             fh = (short)l;
  251.  
  252.             /* Programmierstunde: wir versenden eine Datei mittels XACC */
  253.             buffer = xacc_malloc( 1000L );
  254.             if ( buffer != NULL ) {
  255.  
  256.                 for (;;) {
  257.                     l = Fread( fh, 1000L, buffer );
  258.                     if ( l <= 0L ) {
  259.                         do_sendpiece( xaccs[i].id, message, TRUE, buffer, 0L );
  260.                         break;
  261.                     }
  262.                     if ( !do_sendpiece( xaccs[i].id, message, l < 1000L, buffer, l ) )
  263.                         break;
  264.                     if ( l < 1000L ) break;
  265.                 }
  266.                 Mfree( buffer );
  267.             }
  268.             else form_falert( 1, "[3][* Fehler bei xacc_malloc()][ OK ]" );
  269.  
  270.             Fclose( fh );
  271.         }
  272.     }
  273. }
  274.  
  275. /* eine GEM-Metadatei mittels ACC_META versenden */
  276. void    do_meta( short i )
  277. {
  278.     do_sendfile( i, "GEM", ACC_META );
  279. }
  280.  
  281. /* eine GEM-Imagedatei mittels ACC_IMG versenden */
  282. void    do_img( short i )
  283. {
  284.     do_sendfile( i, "IMG", ACC_IMG );
  285. }
  286.  
  287.  
  288. /* das Copyright des genialen & begnadeten Programmieres ausgeben :-) */
  289. void    do_info( void )
  290. {
  291.     form_falert( 1, "[1][ |xAcc - Testprogramm|(c) 1993 Harald Sommerfeldt][  OK  ]" );
  292. }
  293.  
  294. /* der Hauptdialog, der in der ACC-Version die Menzeile ersetzt */
  295. void    do_dialog( void )
  296. {
  297.     OBJECT    *dialog = rsrc_gtaddr( DIALOG );
  298.     short    x, y, w, h, obj;
  299.     short    i;
  300.  
  301.     wind_update( BEG_UPDATE );
  302.     form_center( dialog, &x, &y, &w, &h );
  303.     form_dial( FMD_START, 0, 0, 0, 0, x, y, w, h );
  304.     objc_draw( dialog, 0, MAX_DEPTH, x, y, w, h );
  305.     obj = form_do( dialog, 0 );
  306.     dialog[obj].ob_state &= ~SELECTED;
  307.     form_dial( FMD_FINISH, 0, 0, 0, 0, x, y, w, h );
  308.     wind_update( END_UPDATE );
  309.     switch ( obj ) {
  310.         case DO_INFO:
  311.             do_info();
  312.             break;
  313.         case DO_KEY:
  314.             if ( (i = do_list( "sende Taste ...", 1 )) >= 0 ) do_key( i );
  315.             break;
  316.         case DO_TEXT:
  317.             if ( (i = do_list( "sende Text ...", 1 )) >= 0 ) do_text( i );
  318.             break;
  319.         case DO_META:
  320.             if ( (i = do_list( "sende GEM-Metadatei ...", 2 )) >= 0 ) do_meta( i );
  321.             break;
  322.         case DO_IMG:
  323.             if ( (i = do_list( "sende GEM-Imagedatei ...", 2 )) >= 0 ) do_img( i );
  324.             break;
  325.     }
  326. }
  327.  
  328. /* GEM-Nachrichten Dispatcher, wird u.a. rekursiv von do_sendpiece() aufgerufen */
  329. bool    handle_mesag( const short *msgbuf )
  330. {
  331.     short    i;
  332.  
  333.     if ( !xacc_message( msgbuf ) ) switch ( msgbuf[0] ) {
  334.  
  335.         case AC_OPEN:                /* ACC-Eshortrag angew„hlt */
  336.             if ( menu != NULL ) do_dialog();
  337.             else form_falert( 1, "[3][ |XACCTEST.RSC nicht geladen][Abbruch]" );
  338.             break;
  339.  
  340.         case MN_SELECTED:            /* Meneshortrag angeklickt */
  341.             switch( msgbuf[4] ) {
  342.                 case MINFO:
  343.                     do_info();
  344.                     break;
  345.                 case MS_KEY:
  346.                     if ( (i = do_list( "sende Taste...", 1 )) >= 0 ) do_key( i );
  347.                     break;
  348.                 case MS_TEXT:
  349.                     if ( (i = do_list( "sende Text...", 1 )) >= 0 ) do_text( i );
  350.                     break;
  351.                 case MS_META:
  352.                     if ( (i = do_list( "sende GEM-Metadatei...", 2 )) >= 0 ) do_meta( i );
  353.                     break;
  354.                 case MS_IMG:
  355.                     if ( (i = do_list( "sende GEM-Imagedatei...", 2 )) >= 0 ) do_img( i );
  356.                     break;
  357.                 case MQUIT:
  358.                     return FALSE;        /* Programmende */
  359.             }
  360.             menu_tnormal( menu, msgbuf[3], TRUE );
  361.             break;
  362.  
  363.         case ACC_ACK:
  364.             /* ein Empf„nger will uns Kunde tun von seiner Begeisterung auf
  365.                 die ACC_TEXT, ACC_KEY, ACC_META oder ACC_IMG-Nachricht, die
  366.                 wir ihm geschickt hatten, msgbuf[3] enth„lt den
  367.                 Begeisterungsgrad: 0 (durchgefallen) oder 1 (bestanden) */
  368.             form_falert( 1, ( msgbuf[3] ) ? "[1][ |ACC_ACK TRUE|empfangen][  OK  ]"
  369.                                           : "[1][ |ACC_ACK FALSE|empfangen][  OK  ]" );
  370.             break;
  371.  
  372.         case ACC_TEXT:
  373.             /* es wird versucht, uns einen Text anzudrehen */
  374.             {    char    buffer[22];
  375.  
  376.                 strncpy( buffer, *(char **)(msgbuf+4), 20 )[20] = '\0';
  377.                 if ( form_falert( 1, "[1][ |ACC_TEXT \"%s\"|empfangen][OK|nicht OK]", buffer ) == 1 )
  378.                     xacc_ack( msgbuf[1], TRUE );
  379.                 else
  380.                     xacc_ack( msgbuf[1], FALSE );
  381.             }
  382.             break;
  383.         case ACC_KEY:
  384.             /* es wird versucht, uns eine Taste anzudrehen */
  385.             if ( form_falert( 1, "[1][ |ACC_KEY %#06x|empfangen][OK|nicht OK]", msgbuf[3] ) == 1 )
  386.                 xacc_ack( msgbuf[1], TRUE );
  387.             else
  388.                 xacc_ack( msgbuf[1], FALSE );
  389.             break;
  390.         case ACC_META:
  391.             /* es wird versucht, uns eine GEM-Metadatei anzudrehen */
  392.             if ( form_falert( 1, "[1][ |ACC_META %d %p %ld|empfangen][OK|nicht OK]",
  393.                                  msgbuf[3], *(char **)(msgbuf+4), *(long *)(msgbuf+6) ) == 1 )
  394.                 xacc_ack( msgbuf[1], TRUE );
  395.             else
  396.                 xacc_ack( msgbuf[1], FALSE );
  397.             break;
  398.         case ACC_IMG:
  399.             /* es wird versucht, uns eine GEM-Imagedatei anzudrehen */
  400.             if ( form_falert( 1, "[1][ |ACC_IMG %d %p %ld|empfangen][OK|nicht OK]",
  401.                                  msgbuf[3], *(char **)(msgbuf+4), *(long *)(msgbuf+6) ) == 1 )
  402.                 xacc_ack( msgbuf[1], TRUE );
  403.             else
  404.                 xacc_ack( msgbuf[1], FALSE );
  405.             break;
  406.  
  407.     }
  408.     return TRUE;
  409. }
  410.  
  411. /* und hier nun die Kr”nung: das Hauptprogramm */
  412. short    main( void )
  413. {
  414.     TEDINFO *t;
  415.     const char xaccname[] = "XACC-Testprogramm";
  416.     short    msgbuf[8];
  417.  
  418.     ap_id = appl_init();
  419.     if ( _XMODE==2 ) menu_id = menu_register( ap_id, "  XACC-Testprogramm" );
  420.     else menu_id = -1;
  421.  
  422.     wind_update( BEG_UPDATE );
  423.     if ( rsrc_load( "XACCTEST.RSC" ) ) {
  424.         menu = rsrc_gtaddr( MENU );
  425.         t=(TEDINFO*)((rsrc_gtaddr( SENDTEXT ))[STXT_TXT].ob_spec);
  426.         t->te_ptext[0] = '\0';
  427.     }
  428.     else menu = NULL;
  429.     if ( _XMODE==0 ) {    /* Ich Programm? Du Menzeile darstellen! */
  430.         if ( menu != NULL ) {
  431.             menu_bar( menu, TRUE );
  432.             graf_mouse( ARROW, NULL );
  433.         }
  434.         else form_falert( 1, "[3][ |XACCTEST.RSC nicht geladen][Abbruch]" );
  435.     }
  436.     wind_update( END_UPDATE );
  437.  
  438.     /* XACC-Protokoll anwerfen */
  439.     xacc_init( menu_id, xaccname, (short)sizeof(xaccname), 0x0003 );
  440.  
  441.     for (;;) {
  442.         evnt_mesag( msgbuf );                        /* auf Nachricht warten */
  443.         if ( !handle_mesag( msgbuf ) ) break;    /* und auswerten */
  444.     }
  445.  
  446.     /* XACC-Protokoll abmelden */
  447.     xacc_exit();
  448.  
  449.     appl_exit();
  450.     return 0;
  451. }
  452.